/* 
 * Copyright 2011 kOSMik.
 * This file is part of kOSMik.
 * 
 * kOSMik is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * kOSMik is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with kOSMik.  If not, see <http://www.gnu.org/licenses/>.
 *  
 * kOSMik:
 * Open Street Map - Editor.
 * http://code.google.com/p/swp-dv-ws2010-osm-2/
 */

package de.fuberlin.kosmik.gui.activity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import de.fuberlin.kosmik.R;
import de.fuberlin.kosmik.data.DataBaseConnector;
import de.fuberlin.kosmik.data.DataBaseConnectorImpl;
import de.fuberlin.kosmik.gui.view.adapter.TrackInfoAdapter;
import de.fuberlin.kosmik.gui.view.adapter.TrackInfoAdapter.TrackInfoItem;
import de.fuberlin.kosmik.gui.view.adapter.TrackInfoAdapter.ViewHolderTrackItem;
import de.fuberlin.kosmik.gui.view.adapter.ViewHolder;
import de.fuberlin.kosmik.log.Constants;

/**
 * TrackInfoActivity shows all POIs, ways and areas of a given track.
 * 
 * @author Micha
 */
public class TrackInfoActivity extends TrackActivity implements OnClickListener,
		OnItemClickListener {

	/**
	 * Key of the track id in the bundle.
	 */
	public static final String TRACK_ID = "track_id";
	/**
	 * Bundle key of the boolean which indicates whether the track is a saved
	 * one or not.
	 */
	public static final String IS_SAVED_TRACK = "is_saved_track";
	private long trackId;
	private CharSequence trackName;
	private ListView lstTrackItems;
	private TextView actionBarTitle;
	private ImageButton btnSearch;
	private static final int REQST_EDIT_POI = 1;
	private static final int REQST_EDIT_WAY_AREA = 2;
	private DataBaseConnector db;

	private boolean inSearchMode;
	/**
	 * Reference to the search box in the action bar.
	 */
	EditText actionBarSearchBox;

	/**
	 * Reference to the listAdapter.
	 */
	TrackInfoAdapter listAdapter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.track_info);
		Bundle extras = getIntent().getExtras();
		trackId = extras.getLong(TRACK_ID, -1);
		db = getDataBase();
		trackName = db.getNameFromTrack(trackId);
		findViewsAndRegisterListener();
		registerForContextMenu(lstTrackItems);
		if (savedInstanceState != null) {
			inSearchMode = savedInstanceState.getBoolean("inSearchMode", false);
			if (inSearchMode) {
				showSearchBox();
			}

		}
	}

	@Override
	public void onStart() {
		super.onStart();
		listAdapter.refreshItems();
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		// save search mode and search word for restoring the state after
		// orientation change.
		outState.putBoolean("inSearchMode", inSearchMode);
	}

	private void findViewsAndRegisterListener() {
		lstTrackItems = (ListView) findViewById(R.id.listTrackItems);
		// registerForContextMenu(lstTrackItems);
		listAdapter = new TrackInfoAdapter(this, trackId);
		lstTrackItems.setAdapter(listAdapter);
		// adapter.getFilter().filter("phone");

		lstTrackItems.setOnItemClickListener(this);
		actionBarTitle = (TextView) findViewById(R.id.action_bar_title);
		actionBarTitle.setText(trackName);
		actionBarSearchBox = (EditText) findViewById(R.id.action_bar_search_box);
		actionBarSearchBox.addTextChangedListener(listAdapter);

		btnSearch = (ImageButton) findViewById(R.id.action_bar_search_button);
		btnSearch.setOnClickListener(this);
	}

	/**
	 * Shows search box in the action bar and hides all other buttons.
	 */
	private void showSearchBox() {
		actionBarTitle.setVisibility(View.GONE);
		actionBarSearchBox.setVisibility(View.VISIBLE);
		actionBarSearchBox.requestFocus();
		btnSearch.setImageResource(R.drawable.ic_action_bar_search_close);
		inSearchMode = true;
	}

	/**
	 * Hides search box in the action bar and shows all other buttons.
	 */
	private void hideSearchBox() {
		actionBarSearchBox.setVisibility(View.GONE);
		actionBarTitle.setVisibility(View.VISIBLE);
		btnSearch.setImageResource(R.drawable.ic_action_bar_search);
		actionBarSearchBox.setText("");
		listAdapter.resetSearch();
		inSearchMode = false;
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.action_bar_search_button:
			if (actionBarSearchBox.getVisibility() == View.VISIBLE)
				hideSearchBox();
			else
				showSearchBox();
			break;
		default:

		}

	}

	@Override
	public void onItemClick(AdapterView<?> listView, View itemView, int position, long id) {

		if (!((ViewHolder<?>) itemView.getTag()).isHeader()) {
			ViewHolderTrackItem viewHolder = (ViewHolderTrackItem) itemView.getTag();
			editItem(viewHolder.trackInfoItem);
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		DataBaseConnector dataBase = new DataBaseConnectorImpl(this);
		if (data == null)
			return;
		long itemId = data.getLongExtra("ITEM_ID", -1);
		if (itemId == -1)
			return;
		Bundle tagValueBundle = data.getBundleExtra("KEY_VALUE_BUNDLE");
		// Log.d(Constants.TAG, "onActivityResult:" + tagValueBundle);

		switch (requestCode) {
		case REQST_EDIT_POI:
			if (resultCode == Activity.RESULT_OK) {
				dataBase.setPoiValues(itemId, tagValueBundle);
			}
			break;
		case REQST_EDIT_WAY_AREA:
			if (resultCode == Activity.RESULT_OK) {
				Log.d(Constants.TAG, "wayId:" + itemId);
				for (String key : tagValueBundle.keySet())
					Log.d(Constants.TAG, key + " - " + tagValueBundle.getString(key));
				dataBase.setWayValues(itemId, tagValueBundle);
			}
			break;
		default:
			break;
		}
		dataBase.close();
	}

	/**
	 * Called, when the context menu pop up.
	 */
	@Override
	public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {

		// create context menu for a selected track in lstRecordedTracks
		if (view == lstTrackItems) {
			// get the view of the item that the event occur
			AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
			final View itemView = info.targetView;
			// get the payload, that contains the track name
			if (!((ViewHolder<?>) itemView.getTag()).isHeader()) {
				// inflate context menu options
				getMenuInflater().inflate(R.menu.track_info_context, menu);
			}

		}

		super.onCreateContextMenu(menu, view, menuInfo);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {

		AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
				.getMenuInfo();
		View itemView = info.targetView;
		TrackInfoItem listItem = ((ViewHolderTrackItem) itemView.getTag()).getItem();

		switch (item.getItemId()) {
		case R.id.opt_editItem:
			editItem(listItem);
			break;
		case R.id.opt_removeItem:
			removeItem(listItem);
			break;
		default:
			break;
		}
		return super.onContextItemSelected(item);
	}

	private void editItem(TrackInfoItem item) {
		int rqstCode;
		if (item.itemType == TrackInfoAdapter.ItemType.POI)
			rqstCode = REQST_EDIT_POI;
		else
			rqstCode = REQST_EDIT_WAY_AREA;

		Intent intent = new Intent(this, TagBundleActivity.class);
		intent.putExtra("OSM_FEATURE_BUNDLE", item.tagsBundle);
		intent.putExtra("ITEM_ID", item.id);
		startActivityForResult(intent, rqstCode);
	}

	private void removeItem(TrackInfoItem item) {
		DataBaseConnector database = new DataBaseConnectorImpl(this);
		if (item.itemType == TrackInfoAdapter.ItemType.POI) {
			database.removePoi(item.id);
		} else {
			database.removeWay(item.id);
		}
		database.close();
		listAdapter.refreshItems();
	}
}
